﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CtefCrmImport.Common.Models;
using CtefCrmImport.Common.Interfaces;
using CtefCrmImport.Common.Extensions;
using CtefCrmImport.Common.Enums;

namespace CtefCrmImport.Common.Builders
{
    /// <summary>
    /// Column definition
    /// 0: transaction id
    /// 1: program name
    /// 2: last name
    /// 3: first name
    /// 4: gift date
    /// 5: pay year
    /// 6: employee amount
    /// 7: amount adjustment description
    /// 8: check amount
    /// 9: gift type
    /// 10: status
    /// 11: purpose
    /// 12: recognition name
    /// 13: address 1
    /// 14: address 2
    /// 15: city
    /// 16: state
    /// 17: zip code
    /// 18: email
    /// </summary>
    public class DonationByTransaction : IEntityBuilder<Donation>
    {
        private readonly HashSet<string> supportedProgramTypes;

        public DonationByTransaction()
        {
            supportedProgramTypes = new HashSet<string>
            {
                Constants.EasyMatchProgramTypeGivingDonation,
                Constants.EasyMatchProgramTypeGivingMatch,
                Constants.EasyMatchProgramTypeMatchingGifts,
                Constants.EasyMatchProgramTypeVolunteerGrant,
                Constants.EasyMatchProgramTypeCreditCard,
            };
        }

        public Donation BuildEntity(string input)
        {
            if (string.IsNullOrWhiteSpace(input))
            {
                throw new ArgumentException("Invalid line input.", "input");
            }

            // Use tab delimited format (file should be exported from Excel as unicode text file)
            var fields = input.Split('\t');
            var progType = fields[1].Trim().ToLowerInvariant();
            var address = new Address
            {
                AddressLine1 = fields[13].TrimOrEmpty(),
                AddressLine2 = fields[14].TrimOrEmpty(),
                City = fields[15].TrimOrEmpty(),
                State = fields[16].TrimOrEmpty(),
                Zip = fields[17].TrimOrEmpty()
            };

            var donor = new Donor
            {
                LastName = fields[2].TrimOrDefault("CTEF"),
                FirstName = fields[3].TrimOrDefault("Friend"),
                PrimaryEmail = fields[18].TrimOrEmpty(),
                Address = address
            };

            var donation = new Donation
            {
                LineInput = input,
                From = donor,
                TransactionId = fields[0].TrimOrEmpty(),
                RecognitionName = fields[12].TrimOrEmpty(),
                OtherInfo = string.Format("{0}: {1}", progType.ToUpperInvariant(), fields[7].TrimOrEmpty()),
                FundType = DonationType.GeneralFund,
                Purpose = fields[11].TrimOrEmpty()
            };

            DateTime dt;
            if (DateTime.TryParse(fields[4], out dt))
            {
                donation.Date = dt;
            }

            donation.PaymentInstrument = fields[9].ToPaymentType();
            if (donation.PaymentInstrument == PaymentType.Other)
            {
                donation.OtherInfo += Environment.NewLine + string.Format("Payment type: {0}", fields[6]);
            }

            switch (progType)
            {
                case Constants.EasyMatchProgramTypeGivingDonation:
                case Constants.EasyMatchProgramTypeCreditCard:
                    donation.GiftAmount = decimal.Parse(fields[6].RemoveCurrencySymbol());
                    break;

                case Constants.EasyMatchProgramTypeGivingMatch:
                case Constants.EasyMatchProgramTypeMatchingGifts:
                case Constants.EasyMatchProgramTypeVolunteerGrant:
                    donation.CompanyMatch = decimal.Parse(fields[8].RemoveCurrencySymbol());
                    break;

                default:
                    throw new ArgumentException("Unsupported program type: " + progType, "input");
            }

            return donation;
        }
    }
}
